# 有没有办法让函数在推出之后还能保留状态呢？有！闭包
# 但是，闭包太麻烦

# 生成器:generator
# 使用 yield 表达式定义生成器

def counter():
    i = 0
    while i <= 5:
        yield i
        i += 1


print(counter())  # <generator object counter at 0x10977fc80> 这是一个生成器

for i in counter():
    print(i)
# for 语句：每次从一个可迭代对象中获取一个数据，那么这个counter生成器的作用就是每次调用的时候提供一个数据
# 每次执行到 yield i 的时候就生成一个数据，暂停并且保留状态，下一次执行的时候则从下一个语句 i+= 1 开始执行
# 可以把生成器看作一个制作机器，没调用依次提供一个数据，并且记住当时的状态
# 生成器可以看作成另一种迭代器，它不走回头路，并且也支持 next() 函数

print("=" * 100)

c = counter()
print(next(c))  # 0
print(next(c))  # 1
print(next(c))  # 2
print(next(c))  # 3
print(next(c))  # 4
print(next(c))  # 5
# print(next(c))  # StopIteration 迭代完了

c = counter()


# 不同通过下标访问
# print(c[2])  # TypeError: 'generator' object is not subscriptable(可下标的)


# 使用生成器生成斐波那契数列
def fib():
    back1, back2 = 0, 1
    while True:
        yield back1
        back1, back2 = back2, back1 + back2


print("=" * 100)

f = fib()
print(next(f))  # 0
print(next(f))  # 1
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
